package com.financing.wap.web.filter;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import com.financing.wap.common.ResultMap;
import com.financing.wap.common.ResultMap.STATUS;
import com.financing.wap.common.Session;
import com.financing.wap.common.SessionImpl;
import com.financing.wap.common.SessionUtil;
import com.financing.wap.dto.UserDTO;
import com.financing.wap.service.IUserService;
import com.financing.wap.util.Constants;
import com.financing.wap.util.PropertiesUtils;

/**
 * 登陆权限过滤Filter
 * @author localadmin
 *
 */
public class LoginFilter implements Filter{

	private String encoding = null;
	
	protected final Logger log = LoggerFactory.getLogger(LoginFilter.class);
	
	private static String CONTEXT_PATH = "";
		
	private static final String[] LINKS_REGEX = {
		"^/api/message/msgStatus.*",
		"^/api/visitRecord.*",
		"^/api/order/applyPre",
		"^/api/order/applyPreTmpSM",
		"^/api/fpShopActivityUser/listFpShopActivityUser",
		"^/api/fpShopActivityUser/updateFpShopActivityUser",
		"^/api/news.*",
		"^/api/verifyCode.*",
		"^/login.*", 
		"^/api/forget.*",
		"^/api/logout.*",
		"^/api/login.*",
		"^/api/quickLogin.*",
		"^/css/.*",
		"^/fonts/.*",
		"^/images/.*", 
		"^/script/.*", 
		"^/api/register.*",
		"^/api/otp.*",
		"^/api/product.*",
		"^/api/activity/.*",
		"^/api/activity/share.*",
		"^/api/t/*.*",
		"^/api/user/changepwdForget",
		"^/api/user/forgetLoginPwd",
		"^/api/user/checkotp",
		"^/api/publicActivities.*",
		"^/api/news/about.*",
		"^/api/pmr",
		"^/api/ad",
		"^/api/adQuery",
		"^/api/wx",
		"^/api/fileUpload",
		"^/api/file/downApp",
		"^/api/fileUploadUeditor",
		"^/api/question.*",
		"^/api/productCompany.*",
		"^/api/advert.*",
		"^/api/fund/fdAwkwardness*.*",
		"^/api/fund/fdBuynotice*.*",
		"^/api/fund/fdCompany*.*",
		"^/api/fund/fpFundInfo*.*",
		"^/api/fund/fdManager*.*",
		"^/api/friendshipLink.*",
		"^/activitiesJob.*",
		"^/api/wechat.*",
		"^/api/generateSiteMapXML.xml",
		".*\\.jsp$",
		"^/api/t/*.*",
		"^/api/mollionsWealth/mollionsWealthProductList",
		"^/api/mollionsWealth/mollionsWealthCount",
		"^/api/fund/.*",
		"^/api/moneyQuestion/.*",
		"^/api/commentsProduct/list.*",
		"^/api/moneyQuestion/.*",
		"^/api/activitiesWinList/.*",
		"^/api/QRcode/m2productDetail",//产品详情二维码图片生成
//		"^/api/notice/.*",
		"^/api/projectLike/listAll.*",
		"^/api/projectLike/productInfo.*",
		"^/api/comm/.*",
		"^/api/count/hybxCount.*",
		"^/api/order/applyPreMD.*",
		"^/api/getproductVideoUrl",
		"^/api/recommentProduct/queryRecommentProduct",
		"^/api/activitiesGroup/shareGroupInfo",
		"^/api/try/kljh/.*",
		"^/api/try/fbh",
		"^/api/wechat/jsapiwxconfig",
		"^/api/biddingReceipt/queryBiddingReceipt",
		"^/api/notice/queryNoticeDate",
		"^/api/biddingReceipt/queryBiddingReceipt",
		"^/api/addUserAgreeAgreement",
		"^/api/queryAgreeAgreement",
		"^/api/user/getUserSaySayForLonginName",
		"^/api/user/getUserForLonginName",
        "^/api/user/forLonginNameGet.*",
		"^/api/fpVideo/.*",
		"^/api/shopperProduct/addShopProductShare",
			"^/api/fpPhoneClient/statistics.*",
		"^/api/fpClientActivity/listFpClientActivity",
		"^/api/fpClientActivity/detailFpClientActivity",
		"^/api/fpClientActivityUser/addFpClientActivityUser",
		"^/api/fpClientOrder/addFpClientOrder",
		"^/api/fpFaUserSaysayComment/addFpFaUserSaysayComment",
		"^/api/fpFaUserSaysayComment/listFpFaUserSaysayComment",
		"^/api/shopperProduct/shopProductList",
		"^/api/fpFaUserSaysay/listFpFaUserSaysay",
		"^/api/userShopperVistCount/shopVistSort",
		"^/api/userShopperVistCount/shopUserVistSort",
		"^/api/userShopperVistCount/getActivityTime",
		"^/api/fpShopUserRelProduct/detailFpShopUserRelProduct",
		"^/api/QRcode/prodqrcode",
		"^/api/fpShopInformation/queryInformation",
		"^/api/fpShopInformationDz/addFpShopInformationDz",
		"^/api/compositeIndexLog/listCompositeIndexLog",
		"^/api/fpShopInformation/detailFpShopInformation",
		"^/api/fpShopInformation/countInformation",
		"^/api/fpShopSignin/queryTopTen",
		"^/api/fpShopPlayopenApply/addFpShopPlayopenApply"   //金策师直播平台申请
	};
	
	@Override
	public void destroy() {
		log.debug("destroy login filter");
		
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain filterChain) throws IOException, ServletException {
		

		HttpServletRequest httpRequest =  (HttpServletRequest)request;
		HttpServletResponse httpResponse = (HttpServletResponse)response;
		
		httpRequest.setCharacterEncoding(encoding);
		httpResponse.setCharacterEncoding(encoding);

		String requestUri = httpRequest.getRequestURI();
		httpResponse.setHeader("Access-Control-Allow-Origin", PropertiesUtils.getValue("Access_Control_Allow_Origin"));
		httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
		httpResponse.setHeader("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE");
		httpResponse.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept,Authorization");
		httpResponse.setHeader("P3P","CP='IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT CAO PSA OUR'");
//		httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
//		System.out.println("=====================>:"+httpRequest.getSession().getId());
		
		Session session = (Session)httpRequest.getSession(true).getAttribute(Session.KEY_NAME);
		
		
		if(!needLogin(requestUri)){
			filterChain.doFilter(request, response);
			return;
		}
		
		log.info("url:"+httpRequest.getRequestURL().toString());
		log.info("seesion ID:"+SessionUtil.getHttpRequest().getRequestedSessionId());
		
		if(session == null || session.getLogin() == false){
			log.info("Not login ,plase login frist.....");
			//记录登陆前的URL
			preRequestRember(httpRequest);
			
			ResultMap result = new ResultMap();
			result.setStatus(STATUS.NEED_LOGIN);
			result.setStatusCode(ResultMap.STATUS_CODE_ONLOGIN);
			result.setMessage("Need login");
			result.setAttribute(Constants.ResultMessage,"未登录,请先登录");
			PrintWriter pw = response.getWriter();
			pw.write(JSONObject.fromObject(result).toString());
			return;
		}
		
		filterChain.doFilter(request, response);
	}
	
	/**
	 * 判断当前请求是否需要登陆
	 * @param requestUri
	 */
	private boolean needLogin(String requestUri){
		
		if(StringUtils.isEmpty(requestUri) || requestUri.equals(CONTEXT_PATH)){
			return false;
		}else{
			requestUri = requestUri.replaceFirst(CONTEXT_PATH, "");
		}
		
		/**
		 *排除根目录 
		 */
		if(requestUri.equals("/")){
			return false;
		}
		
		/**
		 * 排除满足正则的URL
		 */
		for(int i=0; i < LINKS_REGEX.length; i++){
			String regex = LINKS_REGEX[i];
			if(requestUri.matches(regex)){
				return false;
			}
		}
		
		return true;
	}
	
	/**
	 * 初始化Filter
	 */
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		log.debug("init login filter");
		this.encoding = filterConfig.getInitParameter("encoding");
		ServletContext context = filterConfig.getServletContext();
		CONTEXT_PATH = context.getContextPath();
	}
	
	/**
	 * 记录请求前的参数信息
	 * @param request
	 */
	@SuppressWarnings(value={"unchecked"})
	private void preRequestRember(HttpServletRequest request){
		Session session = (Session) request.getSession(true).getAttribute(Session.KEY_NAME);
		if(session == null){
			session = new SessionImpl();
			request.getSession(true).setAttribute(Session.KEY_NAME, session);
		}
		String requestURL = request.getRequestURI();
		requestURL = requestURL.replaceFirst(CONTEXT_PATH, "");
		String method = request.getMethod();
		Map<String, Object> parameter = request.getParameterMap();
		Map<String, Object> paramMap = new HashMap<String, Object>();
		//进行参数拷贝，防止请求结束参数销亡
		copyMap(parameter, paramMap);
		session.setAttribute("returnUrl", requestURL);
		session.setAttribute("returnParameterMap",  paramMap);
		session.setAttribute("returnMethod", method);
	}
	
	/**
	 * 工具方法，后面需要提取到公共的方法类里面
	 * ==============================
	 * 用户Map的拷贝
	 * @param source
	 * @param target
	 */
	private void copyMap(Map<String, Object> source, Map<String, Object> target){
		Set<String> keySet = source.keySet();
		Iterator<String> iterator = keySet.iterator();
		while(iterator.hasNext()){
			String key = iterator.next();
			Object value = (Object) source.get(key);
			target.put(key, value);
		}
		
	}
}
